﻿

#region System

using System;
using System.Text;
using System.Windows.Forms;

#endregion


//脚本
#region  Script

using Newtonsoft.Json;
using System.Xml.Linq;
using System.Linq;

#endregion


//IO
#region IO

using System.IO;


#endregion


//用户自定义
#region Custom

using EasyTCP;
using System.Collections.Generic;
using System.Threading;
using IServer.protobuf;
using System.Runtime.InteropServices;

#endregion



namespace IClient
{
    public partial class mainWindow : Form
    {
        public mainWindow( )
        {
            InitializeComponent( );
        }

        private void mainWindow_Load( object sender, EventArgs e )
        {
            linkServer( );
        }

        private void linkServer( )
        {
            //地址
            var ip = globalData.getValue( "ip" );
            var port = globalData.getValue( "port" );

            this.label1.Text = Login.name + " 正在桥接远程主机...";
            new Thread( ( ) =>
            {
                Control.CheckForIllegalCrossThreadCalls = false;

                EasyClient.bufferEncoder = Encoding.UTF8;
                EasyClient.onConnectServerSucceed += delegate
                {
                    //更新用户状态
                    text_connectServer.Text = "远程主机桥接成功!!!";
                    this.label1.Text = Login.name + " 已进入世界服务器...";

                    //必要的信息
                    var t = new UserInfo( );
                    t.name = Login.name;
                    t.ID = globalData.getValue( "sole_id" );

                    //消息封装
                    var msg = new MsgData( );
                    msg.type = globalData.first_login ? MsgType.Register : MsgType.Login;
                    msg.data = JsonConvert.SerializeObject( t );

                    //发送给服务器
                    EasyClient.Send( JsonConvert.SerializeObject( msg ) );
                };
                EasyClient.onDataReceivedCallback += onDataReceived;
                EasyClient.Launch( $"{ip}:{port}" );

            } ).Start( );
        }

        //接受数据
        public void onDataReceived( string buffer )
        {
            var msg = JsonConvert.DeserializeObject<MsgData>( buffer );
            switch ( msg.type )
            {

                case MsgType.Register:
                    register_success_result_proc( msg );
                    break;
                case MsgType.Login:
                    login_success_result_proc( msg );
                    break;
                case MsgType.FriendEvent:
                    welcome_new_friend( msg );
                    break;
                case MsgType.Logout:
                    saybye_friend( msg );
                    break;
                case MsgType.LostConnection:
                    break;
                case MsgType.LostReconnect:
                    break;
                case MsgType.Chat:
                    receive_chat_proc( msg );
                    break;
                default:
                    break;
            }
        }

        //好友列表
        Dictionary<string, UserInfo> _firends = new Dictionary<string, UserInfo>( );
        //自己的信息
        UserInfo selfInfo = null;

        //注册成功
        private void register_success_result_proc( MsgData msg )
        {

            var data = JsonConvert.DeserializeObject<register_success_result>( msg.data );

            selfInfo = data.info;
            globalData.setValue( "sole_id", data.info.ID );

            friend_list_proc( data.friends );
        }

        //登陆成功
        private void login_success_result_proc( MsgData msg )
        {
            var data = JsonConvert.DeserializeObject<login_success_result>( msg.data );
            selfInfo = data.info;

            friend_list_proc( data.friends );
            offline_proc( data.message );
        }

        //好友列表
        private void friend_list_proc( UserInfo[] friends )
        {
            foreach ( var f in friends )
            {
                UserInfo user = null;
                if ( _firends.TryGetValue( f.ID, out user ) )
                {
                    //刷新
                    user.name = f.name;
                    user.ID = f.ID;
                    user.state = f.state;
                    this.ChatList.Items[user.index] = $"{f.name}({( user.state == 2 ? "online" : "offline" )})";
                }
                else
                {
                    //新增
                    f.index = this.ChatList.Items.Add( $"{f.name}({( user.state == 2 ? "online" : "offline" )})" );
                    _firends.Add( f.ID,f );
                }
            }
        }

        //离线消息
        private void offline_proc( List<chat_data> offlineChats )
        {

        }

        //新的朋友加入
        private void welcome_new_friend( MsgData msg )
        {
            var data = JsonConvert.DeserializeObject<UserInfo>( msg.data );
            _firends.Add( data.ID, data );
            this.ChatList.Items.Add( $"{data.name}(online)" );
        }



        private void saybye_friend( MsgData msg )
        {


            //离线状态刷新
            var data = JsonConvert.DeserializeObject<UserInfo>( msg.data );
            data.index = _firends[data.ID].index;
            _firends[data.ID] = data;
            this.ChatList.Items[data.index] = $"{data.name}({( data.state == 2 ? "online" : "offline" )})";


            //排序 将离线的好友向下靠

        }


        //发送聊天信息
        private void onSendEvent( object sender, EventArgs e )
        {
            if ( this.ChatList.SelectedItems.Count == 0 || string.IsNullOrEmpty( this.inputBox.Text ) )
                return;


            var data = new chat_data( );
            data.from = selfInfo.ID;
            data.chatContent = inputBox.Text;
            data.ts = utils.DateTime2TimeStamp( DateTime.Now ).ToString();

            var msg = new MsgData( );
            msg.type = MsgType.Chat;
            msg.receiver = new string[this.ChatList.SelectedItems.Count];
            msg.data = JsonConvert.SerializeObject( data );

            var chooseReceiver = "";
            for ( int i = 0; i < this.ChatList.SelectedItems.Count;i++ )
            {
                foreach( var user in _firends )
                {
                    if(user.Value.index == i)
                    {
                        msg.receiver[i] = user.Value.ID;
                        chooseReceiver += $"{( i == 0 ? "" : "," )}{ user.Value.name }";
                        break;
                    }
                }
            }

            EasyClient.Send( JsonConvert.SerializeObject( msg ) );
            textBox1.Text += $"\r\nto ->{chooseReceiver} {DateTime.Now.ToString( )}: {this.inputBox.Text}";
            this.inputBox.Clear( );
        }

        //接受聊天信息
        private void receive_chat_proc( MsgData msg )
        {

            var data = JsonConvert.DeserializeObject<chat_data>( msg.data );
            var caller = _firends[data.from].name;
            var time = utils.Ticks2DateTime( Convert.ToInt64( data.ts ) );


            textBox1.Text += $"\r\nfrom <-{caller} {time.ToString( )}: {data.chatContent}";
        }


        private void button1_Click( object sender, EventArgs e )
        {
            //退出
            var msg = new MsgData( );
            msg.type = MsgType.Logout;
            msg.caller = selfInfo.ID;
            EasyClient.Send( JsonConvert.SerializeObject( msg ) );

            //本地数据保存
            globalData.save( );

            timer.Start( );
        }


        #region 无边框拖动效果
        [DllImport( "user32.dll" )]//拖动无窗体的控件
        public static extern bool ReleaseCapture( );
        [DllImport( "user32.dll" )]
        public static extern bool SendMessage( IntPtr hwnd, int wMsg, int wParam, int lParam );
        public const int WM_SYSCOMMAND = 0x0112;
        public const int SC_MOVE = 0xF010;
        public const int HTCAPTION = 0x0002;
        private void onMouseDown( object sender, MouseEventArgs e )
        {
            //拖动窗体
            ReleaseCapture( );
            SendMessage( this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0 );
        }
        #endregion


        #region 右下角最小图标
        private void button3_Click( object sender, EventArgs e )
        {
            this.WindowState = FormWindowState.Minimized;
            this.notifyIcon1.Visible = true;
        }

        private void notifyIcon1_MouseClick( object sender, MouseEventArgs e )
        {
            this.WindowState = FormWindowState.Normal;
            this.notifyIcon1.Visible = false;

        }
        #endregion

        private void timer_Tick( object sender, EventArgs e )
        {
            if ( this.Opacity >= 0.025 )
            {
                this.Opacity -= 0.025;
            }
            else
            {
                timer.Stop( );
                this.Close( );
            }
        }

    }
}
